#include <iostream>
#include <cstdlib>
#include <string>
#include <cassert>
#include <vector>
#include <pthread.h>
#include <unistd.h>

using namespace std;

class ThreadData
{
public:
    int number;
    pthread_t tid;
    char namebuffer[64];
};

class ThreadReturn
{
public:
    int exit_code;
    int exit_result;
};

void *start_routine(void *args)
{
    // sleep(1);

    ThreadData *td = static_cast<ThreadData *>(args); // 安全的进行强制类型转化
    int cnt = 10;
    while (cnt)
    {
        cout << "cnt: " << cnt << " &cnt: " << &cnt << endl; // bug
        cnt--;
        sleep(1);
        
    }

    // return (void *)2024;
    // pthread_exit((void*)111); 
    ThreadReturn * tr = new ThreadReturn();
    tr->exit_code = 4;
    tr->exit_result = 28;

    // ThreadReturn tr; // 在栈上开辟的空间 return &tr; 会出错，野指针

    // return (void*)tr;
    return (void*)428; //右值

}

int main()
{
    //创建一批线程
    vector<ThreadData*> threads;
#define NUM 10
    for(int i = 0; i < NUM; i++)
    {
        ThreadData *td = new ThreadData();
        td->number = i+1;
        snprintf(td->namebuffer, sizeof(td->namebuffer), "%s:%d", "thread", i+1);
        pthread_create(&td->tid, nullptr, start_routine, td);

        threads.push_back(td);
    }

    for(auto &iter : threads)
    {
        cout << "create thread: " << iter->namebuffer << " : " << iter->tid << " suceesss" << endl;
    }
    // 线程是可以被cancel取消的！注意：线程要被取消，前提是这个线程已经跑起来了
    // 线程如果是被取消的，退出码：-1
    // PTHREAD_CANCELED;
    sleep(5);
    for(int i = 0; i < threads.size()/2; i++)
    {
        pthread_cancel(threads[i]->tid);
        cout << "pthread_cancel : " << threads[i]->namebuffer << " success" << endl;
    }

    for(auto &iter : threads)
    {
        void *ret = nullptr; 
        int n = pthread_join(iter->tid, (void**)&ret); 
        assert(n == 0);
        //取消线程，等待收到-1，没取消的 等待后收到428
        cout << "join : " << iter->namebuffer << " success, exit_code: " << (long long)ret << endl;
        delete iter;
    }

    cout << "main thread quit " << endl;


    return 0;
}